package com.lei.zjs.dao.base;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

import javax.annotation.Resource;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.lei.zjs.vo.PageBean;
import com.lei.zjs.vo.Staff;

public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {

	private Class<T> domainClass;

	public BaseDaoImpl() {
		ParameterizedType genericSuperclass = (ParameterizedType) this.getClass().getGenericSuperclass();
		Type[] actualTypeArguments = genericSuperclass.getActualTypeArguments();
		domainClass = (Class<T>) actualTypeArguments[0];
	}
	// 为HibernateDaoSupport注入sessionFactory
	@Resource
	public void setSF(SessionFactory sessionFactory) {
		super.setSessionFactory(sessionFactory);
	}
	
	@Override
	public void save(T entity) {
		this.getHibernateTemplate().save(entity);
	}

	@Override
	public void delete(T entity) {
		this.getHibernateTemplate().delete(entity);
	}

	@Override
	public void update(T entity) {
		this.getHibernateTemplate().update(entity);
	}

	@Override
	public T findById(Serializable id) {
		return this.getHibernateTemplate().get(domainClass, id);
	}

	@Override
	public List<T> findAll() {
		String hql = "FROM " + domainClass.getSimpleName();
		return this.getHibernateTemplate().find(hql );
	}

	@Override
	public List<T> findByNamedQuery(String namedQuery, Object... args) {
		return this.getHibernateTemplate().findByNamedQuery(namedQuery, args);
	}

	@Override
	public void executeByNamedQuery(String namedQuery, Object... args) {
		Session session = this.getSession();
		Query query = session.getNamedQuery(namedQuery);
		if (args != null && args.length > 0) {
			for (int i = 0; i < args.length; i++) {
				query.setParameter(i, args[i]);
			}
		}
		query.executeUpdate();
	}

	@Override
	public List<T> findByCriteria(DetachedCriteria dc) {
		return this.getHibernateTemplate().findByCriteria(dc);
	}

	@Override
	public List<Staff> findByPage(Integer start, int rows) {
		DetachedCriteria dc = DetachedCriteria.forClass(domainClass);
		return this.getHibernateTemplate().findByCriteria(dc, start, rows);
	}

	@Override
	public Long findCount() {
		DetachedCriteria dc = DetachedCriteria.forClass(domainClass);
		dc.setProjection(Projections.rowCount());
		List<Long> list = this.getHibernateTemplate().findByCriteria(dc);
		return list.get(0);
	}

	@Override
	public void pageQuery(PageBean pageBean) {
		Integer currentPage = pageBean.getCurrentPage();
		Integer pageSize = pageBean.getPageSize();
		
		//投影查询 总记录数
		DetachedCriteria criteria = pageBean.getDetachedCriteria();
		criteria.setProjection(Projections.rowCount());
		List<Long> list = this.getHibernateTemplate().findByCriteria(criteria);
		Long total = list.get(0);
		
		//清除投影查询条件,并重置结果集内容为实体对象
		criteria.setProjection(null);
		criteria.setResultTransformer(DetachedCriteria.ROOT_ENTITY);
		int firstResult = (currentPage - 1) * pageSize;
		int maxResults = pageSize;
		List<Staff> staffs = this.getHibernateTemplate().findByCriteria(criteria, firstResult, maxResults );
		
		pageBean.setTotal(total);
		pageBean.setRows(staffs);
	}
}

